package com.gamesite.gamesite.games.TicTacToe.socket.endpoint;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gamesite.gamesite.core.pojo.GameRoom;
import com.gamesite.gamesite.core.pojo.User;
import com.gamesite.gamesite.core.service.UserService;
import com.gamesite.gamesite.core.vo.RoomPlayerVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;


@ServerEndpoint("/ws/TicTacToe")
@Component
public class WsTicTacToeEndpoint {
    private static final Set<Session> sessions = Collections.synchronizedSet(new HashSet<>());
    private static final Map<Session, User> userMap = new HashMap<>();
    private static final Map<Long, GameRoom> roomMap = new HashMap<>();
    private static UserService userService;

    @Autowired
    public void initWsTicTacToeEndpoint(UserService userService) {
        WsTicTacToeEndpoint.userService = userService;
    }
    @OnOpen
    public void onOpen(Session session) {
        sessions.add(session);
        System.out.println("Connected: " + session.getId());
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("Message from " + session.getId() + ": " + message);
        try {
            // 解析消息
            JSONObject jsonMessage = JSONObject.parseObject(message);
            String type = jsonMessage.getString("type");
            switch (type) {
                case "setId":
                    bindSessionUserInfo(session, jsonMessage);
                    break;
                case "startGame":
                    handleStartGame(session, jsonMessage);
                    break;
                case "newStep"://处理新步骤
                    newStep(session, jsonMessage);
                    break;
                case "leaveGame":
                    handleLeaveGame(session, jsonMessage);
                case "endGame":
                    //处理游戏结束
                    endGame(session, jsonMessage);
                    break;
                default:
                    System.out.println("未知消息类型: " + type);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 示例：广播消息给所有客户端
//        sessions.forEach(s -> {
//            try {
//                s.getBasicRemote().sendText("Echo: " + message);
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        });
    }

    private void handleLeaveGame(Session session, JSONObject jsonMessage) {
        //将该房间中的每个玩家都从房间中移除
        Long roomId = jsonMessage.getLong("roomId");
        GameRoom room = roomMap.get(roomId);
        if (room != null) {
            List<RoomPlayerVo> playerList = room.getPlayerList();
            for (RoomPlayerVo player : playerList) {
                Session playerSession = null;
                for (Map.Entry<Session, User> entry : userMap.entrySet()) {
                    if (entry.getValue().getId().equals(player.getId())) {
                        playerSession = entry.getKey();
                        break;
                    }
                }
                if (playerSession != null) {
                    try {
                        //发送消息给玩家 告诉玩家房间已经解散
                        ObjectMapper objectMapper = new ObjectMapper();
                        Map<String, Object> messageReturn = new HashMap<>();
                        messageReturn.put("type", "playerLeave");
                        messageReturn.put("roomId", roomId);
                        messageReturn.put("message", "玩家"+userMap.get(session).getUsername()+"离开了房间");
                        playerSession.getBasicRemote().sendText(objectMapper.writeValueAsString(messageReturn));

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }


    @OnClose
    public void onClose(Session session) {
        // 移除session
        User user = userMap.get(session);
        sessions.remove(session);
        userMap.remove(session);
        System.out.println("Disconnected: " + session.getId());
        //向房间中其他用户广播，有用户离开

        if (user != null) {
            for (Map.Entry<Session, User> entry : userMap.entrySet()) {
                if (!entry.getKey().equals(session)) {
                    try {
                        entry.getKey().getBasicRemote().sendText("用户 " + user.getUsername() + " 离开了房间");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    private void bindSessionUserInfo(Session session, JSONObject jsonMessage) {
        // 从数据库中获取用户信息
        Integer userId = Integer.parseInt(jsonMessage.getString("userId"));
        User user = userService.getById(userId);
        if (user != null) { // 确保用户对象不为null
            userMap.put(session, user);
        } else {
            System.err.println("User not found with ID: " + userId);
        }
    }
    private void handleStartGame(Session session, JSONObject jsonMessage) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> messageReturn = new HashMap<>();
        Long roomId = jsonMessage.getLong("roomId");
        List<RoomPlayerVo> playerList=jsonMessage.getJSONArray("playerList").toJavaList(RoomPlayerVo.class);
        GameRoom room = roomMap.get(roomId);
        if (roomId != null) {
            if (room == null) {
                room = new GameRoom();
                room.setRoomId(roomId);
                room.setPlayerList(playerList);
                roomMap.put(roomId, room);
            }
        }
        //在玩家列表中随机挑选一个玩家作为先手开始游戏 给定玩家id
        int index = new Random().nextInt(2);
        messageReturn.put("type", "startGame");
        messageReturn.put("roomId", roomId);
        messageReturn.put("playerList", playerList);
        messageReturn.put("firstPlayerId", playerList.get(index).getId());
        //将消息发给房间内玩家列表中的每一个玩家
        for (RoomPlayerVo player : playerList) {
            Session playerSession = null;
            for (Map.Entry<Session, User> entry : userMap.entrySet()) {
                if (entry.getValue().getId().equals(player.getId())) {
                    playerSession = entry.getKey();
                    break;
                }
            }
            if (playerSession != null) {
                playerSession.getBasicRemote().sendText(objectMapper.writeValueAsString(messageReturn));
            }
        }
    }

    private void  newStep(Session session, JSONObject jsonMessage) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> messageReturn = new HashMap<>();
        Long roomId = jsonMessage.getLong("roomId");
        Integer playerId=jsonMessage.getInteger("playerId");
        List<RoomPlayerVo> playerList=jsonMessage.getJSONArray("playerList").toJavaList(RoomPlayerVo.class);
        String newstep=jsonMessage.getString("newstep");
        Long nextPlayerId=getNextPlayerId(playerList,playerId.longValue());
        messageReturn.put("type", "newStep");
        messageReturn.put("roomId", roomId);
        messageReturn.put("newstep",newstep);//下的位置
        messageReturn.put("nextPlayerId", nextPlayerId);//下一个人的id
        //将消息发给房间内玩家列表中的每一个玩家
        for (RoomPlayerVo player : playerList) {
            Session playerSession = null;
            for (Map.Entry<Session, User> entry : userMap.entrySet()) {
                if (entry.getValue().getId().equals(player.getId())) {
                    playerSession = entry.getKey();
                    break;
                }
            }
            if (playerSession != null) {
                playerSession.getBasicRemote().sendText(objectMapper.writeValueAsString(messageReturn));
            }
        }
    }
    private void endGame(Session session, JSONObject jsonMessage) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> messageReturn = new HashMap<>();
        Long roomId = jsonMessage.getLong("roomId");
        List<RoomPlayerVo> playerList=jsonMessage.getJSONArray("playerList").toJavaList(RoomPlayerVo.class);
        Long winnerId=jsonMessage.getLong("winnerId");
        messageReturn.put("type", "endGame");
        messageReturn.put("roomId", roomId);
        messageReturn.put("winnerId",winnerId);
        //将消息发给房间内玩家列表中的每一个玩家
        for (RoomPlayerVo player : playerList) {
            Session playerSession = null;
            for (Map.Entry<Session, User> entry : userMap.entrySet()) {
                if (entry.getValue().getId().equals(player.getId())) {
                    playerSession = entry.getKey();
                    break;
                }
            }
            if (playerSession != null) {
                playerSession.getBasicRemote().sendText(objectMapper.writeValueAsString(messageReturn));
            }
        }
    }
    public Long getNextPlayerId(List<RoomPlayerVo> playerList, Long currentUserId) {
        if (playerList == null || playerList.isEmpty()) {
            return null; // 或者抛出异常，取决于你的需求
        }

        int size = playerList.size();
        for (int i = 0; i < size; i++) {
            RoomPlayerVo player = playerList.get(i);
            if (player.getId().equals(currentUserId)) {
                // 如果最后一个玩家是当前用户，则返回第一个玩家的ID，形成循环
                if (i == size - 1) {
                    return playerList.get(0).getId();
                } else {
                    // 否则返回下一个玩家的ID
                    return playerList.get(i + 1).getId();
                }
            }
        }
        // 如果没有找到当前用户ID，可能是输入错误或用户不在列表中，此时可以返回null或者第一个玩家的ID作为默认值
        return playerList.get(0).getId(); // 或者选择抛出异常/返回null等处理方式
    }


}
